package com.ctvit.syn.service;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import antlr.debug.SyntacticPredicateAdapter;


public class SynchronizeDataService extends SyncDataBaseService {

	private Logger logger = LoggerFactory.getLogger(SynchronizeDataService.class);
	private ToRemoteSynService toRemoteSynService;
	public void synchronizeDataEmergent(List<SyncTableInfo> syncTableInfos) throws Exception {
		Date startTime = new Date();
		logger.info(" start to sync data emergentcy....");
		String[] opS=null;
		Date lastSynDate=null;
		for (SyncTableInfo syncTableInfo : syncTableInfos) {
			opS=syncTableInfo.getOp().split(",");
			for (int i = 0; i < opS.length; i++) {
				lastSynDate = getLastSynDate(syncTableInfo.getSourceDb(),syncTableInfo.getDestDb(),syncTableInfo.getTablename(), opS[i]);
				if (StringUtils.equals(opS[i], "insert")){
					toRemoteSynService.insertTableData(syncTableInfo, lastSynDate, startTime,syncTableInfo.getSourceDb(),syncTableInfo.getDestDb());
				}else if (StringUtils.equals(opS[i], "update")){
					toRemoteSynService.updateTableData(syncTableInfo, lastSynDate, startTime, syncTableInfo.getSourceDb(),syncTableInfo.getDestDb());
				}else if (StringUtils.equals(opS[i], "delete")){
					toRemoteSynService.delTableData(syncTableInfo, lastSynDate, startTime, syncTableInfo.getSourceDb(),syncTableInfo.getDestDb());
				}
			}
		}
		logger.info(" finish to sync data emergentcy. ");
	}
	public void synchronizeData() throws Exception {
		// 时钟前移5分钟，是为了保证ET1服务器时钟比EC服务器时钟快
		Date startTime = new Date();
		int min = 5;
		/*Statement stmt = null;
		ResultSet rs = null;
		try{
			stmt = getConn().createStatement();
			rs = stmt.executeQuery("select t.value from base_config t where t.name='sync'");
			String str = null;
			while(rs.next()){
				str = rs.getString(1);
			}
			if(!"".equals(str)&&str!=null){
				min = Integer.parseInt(str);
			}
		}catch(Exception e){
			throw e;
		}finally{
			JDBCUtil.closeResultSet(rs);
			JDBCUtil.closeStatement(stmt);
			JDBCUtil.closeConnection(connection);
		}*/

//		startTime = new Date(startTime.getTime() - min * 60 * 1000);

//		logger.info(" front time is " + min + " min .......");
		logger.info(" start to sync data....");
//		synClotResume(startTime);
		synDataNow(startTime);
		logger.info(" finish to sync data. ");
	}

	public void test() throws Exception {
		try {
			SyncTableInfo tableInfo = new SyncTableInfo();
			tableInfo.setTablename("t_recv_system");
			tableInfo.setPkFieldName(new String[]{"z_sys_id"});

			logger.info(" synchronize table: " + tableInfo.getTablename());
//			toRemoteSynService.syncTableDate(tableInfo);
		} catch (Exception e) {
			throw e;
		}
	}

	protected void synClotResume(Date now) throws Exception {
		try {
			SyncTableInfo tableInfo = new SyncTableInfo();
			tableInfo.setTablename("t_sync_test");
			tableInfo.setPkFieldName(new String[]{"f_sync_test_pk"});

			logger.info(" synchronize table: " + tableInfo.getTablename());
//			Date date = toRemoteSynService.getLastSynDate(tableInfo.getTablename(), "insert");
//			toRemoteSynService.insertTableData(tableInfo, date, now);
		} catch (Exception e) {
			throw e;
		}
	}
	protected SyncTableInfo createTableInfo(String name,String[] pkFieStrings,String src,String dest,String op){
		SyncTableInfo tableInfo = new SyncTableInfo();
		tableInfo.setTablename(name);
		tableInfo.setPkFieldName(pkFieStrings);
		tableInfo.setSourceDb(src);
		tableInfo.setDestDb(dest);
		tableInfo.setOp(op);
		return tableInfo;
	}
	protected void synDataNow(Date now) throws Exception {
		try {
			List<SyncTableInfo> syncTableInfos=new ArrayList<SyncTableInfo>();
			SyncTableInfo tableInfo=null;
////			local-->notice
//			tableInfo = createTableInfo("t_worderror",null,"notice","local","insert");
//			syncTableInfos.add(tableInfo);
////			notice-->local
//			tableInfo = createTableInfo("V_NOTICE_MAIN_AVD",null,"notice","local","insert");
//			syncTableInfos.add(tableInfo);
////			notice-->remote
//			tableInfo = createTableInfo("NOTICE_FILE",null,"notice","remote","insert");
//			syncTableInfos.add(tableInfo);
////			local-->remote
			tableInfo = createTableInfo("t_cmsg_meeting",new String[]{"f_message_pk"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_attach",new String[]{"f_attach_pk"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_cmsg_text",new String[]{"f_message_pk"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_cmsg_retrieve",new String[]{"F_ID"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_msg_req",new String[]{"Z_REQ_ID"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_req_meetingnotice",new String[]{"id"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_msg_task",new String[]{"Z_TASK_ID"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_msg_reg",new String[]{"Z_REG_NO"},"local","remote","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_notice",null,"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("NOTICE_FILE",null,"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("zcdm_t_prorec",new String[]{"Z_PRO_REC_CD"},"local","remote","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("zcdm_t_proglist",new String[]{"Z_PRO_ITEM_CD"},"local","remote","insert,update,delete");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("zppm_t_proginfo",new String[]{"z_procode","z_aud_ver","z_cap_ver"},"local","remote","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("zcdm_t_chanl",new String[]{"Z_CHANL_CD"},"local","remote","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("zcdm_t_subj",new String[]{"Z_SUBJ_CD"},"local","remote","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("zcdm_t_monitor",new String[]{"id"},"local","remote","insert,update");
			syncTableInfos.add(tableInfo);
////			remote-->local
			tableInfo = createTableInfo("t_msg_task",new String[]{"Z_TASK_ID"},"remote","local","update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_user_subs",new String[]{"f_user_subsed_pk"},"remote","local","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_user_subs_follow",new String[]{"f_user_subs_follow_pk"},"remote","local","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_user_subs_config",new String[]{"f_user_id"},"remote","local","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_myconcern",new String[]{"f_id"},"remote","local","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_msg_sendlog",new String[]{"z_send_id"},"remote","local","insert");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_calendar_warn",new String[]{"ID"},"remote","local","insert,update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_msg_category",new String[]{"f_msg_category"},"local","remote","update");
			syncTableInfos.add(tableInfo);
			tableInfo = createTableInfo("t_msg_sub_cat",new String[]{"f_msg_sub_cat"},"local","remote","update");
			syncTableInfos.add(tableInfo);
			
			String[] opS=null;
			Date lastSynDate=null;
			for (SyncTableInfo syncTableInfo : syncTableInfos) {
				opS=syncTableInfo.getOp().split(",");
				for (int i = 0; i < opS.length; i++) {
					lastSynDate = getLastSynDate(syncTableInfo.getSourceDb(),syncTableInfo.getDestDb(),syncTableInfo.getTablename(), opS[i]);
					if (StringUtils.equals(opS[i], "insert")){
						toRemoteSynService.insertTableData(syncTableInfo, lastSynDate, now,syncTableInfo.getSourceDb(),syncTableInfo.getDestDb());
					}else if (StringUtils.equals(opS[i], "update")){
						toRemoteSynService.updateTableData(syncTableInfo, lastSynDate, now, syncTableInfo.getSourceDb(),syncTableInfo.getDestDb());
					}else if (StringUtils.equals(opS[i], "delete")){
						toRemoteSynService.delTableData(syncTableInfo, lastSynDate, now, syncTableInfo.getSourceDb(),syncTableInfo.getDestDb());
					}
				}
			}
		} catch (Exception e) {
			throw e;
		}
	}

	//测试用
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				new String[]{"config/application-datasource-basic.xml"});
		SynchronizeDataService synService = (SynchronizeDataService) context.getBean("synchronizeDataService");
		try {
			synService.synchronizeData();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ToRemoteSynService getToRemoteSynService() {
		return toRemoteSynService;
	}

	public void setToRemoteSynService(ToRemoteSynService toRemoteSynService) {
		this.toRemoteSynService = toRemoteSynService;
	}
}
